/*
 * File Name：CWVideoPallete.java
 * Copyright：Copyright 2008-2012 CiWong.Inc. All Rights Reserved.
 * Description： CWVideoPallete.java
 * Modify By：PLA-ZJLIU
 * Modify Date：2012-12-12
 * Modify Type：Add
 */
package com.ciwong.ciwongwrite.widget;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.CRC32;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.widget.FrameLayout;

import com.ciwong.ciwongwrite.JournalActivity;
import com.ciwong.ciwongwrite.mode.TrackBase;
import com.ciwong.ciwongwrite.mode.TrackCls;
import com.ciwong.ciwongwrite.mode.TrackEaser;
import com.ciwong.ciwongwrite.mode.TrackHeader;
import com.ciwong.ciwongwrite.mode.TrackMouse;
import com.ciwong.ciwongwrite.mode.TrackMove;
import com.ciwong.ciwongwrite.mode.TrackPhoto;
import com.ciwong.ciwongwrite.utils.CWUtils;

/**
 *
 * <pre>
 * </pre>
 *
 * @author PLA-ZJLIU
 * @version ciwong v.1.0 2012-12-12
 * @since ciwong v.1.0
 */
@SuppressLint("NewApi")
public class CWPallete extends FrameLayout
{

    private static final int SAVING_COMPLETE = 0;

    private Pallete mPallete;

    private JournalActivity activity;
    public  int SCREEN_HEIGHT;
    public  int SCREEN_WIDTH;

    public CWPallete(Context context)
    {
        super(context);
        init(context);
    }

    public CWPallete(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        init(context);
    }

    public CWPallete(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(Context context)
    {
        mPallete = new Pallete(context);
        activity =(JournalActivity)context; final DisplayMetrics outMetrics = getResources().getDisplayMetrics();
        if (outMetrics.widthPixels < outMetrics.heightPixels) {
            SCREEN_HEIGHT = outMetrics.widthPixels;
            SCREEN_WIDTH = outMetrics.heightPixels;
        } else {
            SCREEN_WIDTH = outMetrics.widthPixels;
            SCREEN_HEIGHT = outMetrics.heightPixels;
        }
        SCREEN_WIDTH=CWUtils.px2dip(context,SCREEN_HEIGHT);
        LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT);
        mPallete.setLayoutParams(lp);
        addView(mPallete);
    }

    public void setColor(int color)
    {
        mPallete.setColor(color);
    }

    public void setWidth(int width)
    {
        mPallete.setWidth(width);
    }

    public void setImagePath(String path)
    {
        mPallete.setImagePath(path);
    }
    public Bitmap getBitmap()
    {
        return mPallete.getScreen();
    }

    public void insertImageResult(Intent data, int requestCode)
    {
        mPallete.insertImage(data, requestCode);
    }

    public static interface CWVideoPanelListener
    {
        public void insertImage(int requestCode);

    }

    public void setEaser()
    {
        mPallete.setTrackAction(TrackBase.TRACK_ACTION_EASER);
    }

    public void clearScreen()
    {
        mPallete.clsScreen();
    }

    public boolean isWrite()
    {
        return mPallete.isWrite();
    }

    public void clearWrite()
    {
        mPallete.clearWrite();
    }

    public void setBrush()
    {
        mPallete.setTrackAction(TrackBase.TRACK_ACTION_MOUSE);
    }

    public void invalit(){
        mPallete. drawCanvas();
    }

    public class Pallete extends View
    {
        public static final int RECORD_STATUS_NORMAL = -1;

        public static final int RECORD_STATUS_RECORDING = 0;

        public static final int RECORD_STATUS_PUASE = 1;

        public static final int RECORD_STATUS_STOP = 2;

        private Canvas mCanvas;

        private Paint mPaint;

        private Bitmap bufferBitmap;

        private TrackMove mCurTrack;

        private TrackBase mRecordTrack;

        private String dataSource;

        private int trackAction = TrackBase.TRACK_ACTION_MOUSE;

        private boolean isSingleTouch, isWrite;// 是否有两个触点,是否有写的操作

        private int color;// 画笔颜色

        private int widthIndex;// 画笔宽度索引

        private int bgColor;// 背景色

        private boolean isDown;// 是否是按下状态

        private TrackHeader mHeader;

        private long startTime;

        private long puaseStartTime;

        private long puaseTime;

        private int curRecordStatus = RECORD_STATUS_NORMAL;

        private Bitmap selectImg;

        private long crcStr;

        private File temp;

        private boolean isDrawed;// 添加图片后是否绘制到画布上

        private Object asyncDraw = new Object();

        private boolean isSaving;

        private File cacheFile;

        private Handler mHandler = new Handler()
        {
            public void handleMessage(Message msg)
            {
                switch (msg.what)
                {
                    case SAVING_COMPLETE:
                        break;
                }
            };
        };

        public Bitmap getScreen()
        {
            return bufferBitmap;
        }

        public boolean isWrite()
        {
            return isWrite;
        }

        public void clearWrite()
        {
            isWrite = false;
        }

        public Pallete(Context context)
        {
            super(context);
            init();
        }

        public Pallete(Context context, AttributeSet attrs)
        {
            super(context, attrs);
            init();
        }

        public Pallete(Context context, AttributeSet attrs, int defStyle)
        {
            super(context, attrs, defStyle);
            init();
        }

        private void init()
        {

            isSingleTouch = true;
            color = TrackBase.COLOR_0;
            widthIndex = 2;
            mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
            mPaint.setFilterBitmap(true);
            bgColor = Color.WHITE;
        }

        private void initBufferBitmap(int width, int height)
        {
            LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,SCREEN_HEIGHT*4);
            mPallete.setLayoutParams(lp);
            if (bufferBitmap == null)
            {
                bufferBitmap = Bitmap.createBitmap(width,  SCREEN_HEIGHT*4,
                        Config.ARGB_8888);
            }
            if (mCanvas == null)
            {
                mCanvas = new Canvas(bufferBitmap);
            }
            mCanvas.setDrawFilter(new PaintFlagsDrawFilter(0,
                    Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
            mCanvas.drawColor(bgColor);
            // initStatus = INIT_STATUS_NORMAL;
        }

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
            final int w = getMeasuredWidth();
            final int h = getMeasuredHeight();
            if (w > 0 && h > 0 && bufferBitmap == null)
            {
                initBufferBitmap(w, h);
                // initRecorder();
            }
        }

        private void insertImg()
        {
            // CWLog.w("debug", "selectImg:" + selectImg + "    crcStr:" +
            // crcStr);
            if (selectImg != null && crcStr != 0)
            {
                TrackPhoto photo = new TrackPhoto(selectImg, crcStr, 0, 0,
                        selectImg.getWidth(), selectImg.getHeight());
                mCurTrack = photo;
                mCurTrack.setRecord();
                trackAction = TrackBase.TRACK_ACTION_PHOTO;
                mRecordTrack = mCurTrack;
                selectImg = null;
                crcStr = 0;
            }
        }

        public void setImagePath(String imagePath)
        {
            Bitmap temp = BitmapFactory.decodeFile(imagePath);
            if (temp == null)
            {
                return;
            }
            Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
            // p.setColorFilter(new );
            final int w = temp.getWidth();
            final int h = temp.getHeight();
            if (w > 0 && h > 0)
            {
                if (this.bufferBitmap != null)
                {
                    this.bufferBitmap.recycle();
                }
                this.bufferBitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);
                mCanvas = new Canvas(bufferBitmap);
                PaintFlagsDrawFilter filter = new PaintFlagsDrawFilter(0,
                        Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
                mCanvas.drawBitmap(temp, 0, 0, p);
                mCanvas.setDrawFilter(filter);
            }
            mCurTrack = null;
            invalidate();
        }

        private void resetRecordStatus()
        {
            if (curRecordStatus != RECORD_STATUS_RECORDING)
            {
                trackAction = TrackBase.TRACK_ACTION_MOUSE;
                mCurTrack = null;
                mRecordTrack = new TrackMouse();
            }

        }

        public String getDataSource()
        {
            return dataSource;
        }

        public int getCurRecordStatus()
        {
            return curRecordStatus;
        }

        public void setColor(int color)
        {
            this.color = color;
        }

        public void setWidth(int width)
        {
            this.widthIndex = width;
        }

        private Bitmap matrix(Bitmap mBitmap)
        {
            final int w = getWidth();
            final int h = getHeight();
            final int bw = mBitmap.getWidth();
            final int bh = mBitmap.getHeight();
            if (bw > w && bh > h)
            {
                float scaleX = (float) w / (float) bw;
                float scaleY = (float) h / (float) bh;
                mBitmap = CWUtils.matrix(mBitmap, Math.min(scaleX, scaleY));
            }
            return mBitmap;
        }

        private void insertImage(Bitmap mBitmap, String imgPath)
        {
            try
            {
                CRC32 crc32 = new CRC32();
                InputStream inStream = null;
                BufferedInputStream in = null;
                if (imgPath == null)
                {
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    mBitmap.compress(CompressFormat.JPEG, 75, out);
                    inStream = new ByteArrayInputStream(out.toByteArray());
                }
                else
                {
                    inStream = new FileInputStream(imgPath);
                }
                in = new BufferedInputStream(inStream);
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = in.read(buffer)) != -1)
                {
                    crc32.update(buffer, 0, len);
                }
                in.close();
                inStream.close();
                crcStr = crc32.getValue();
                final Long tempCrc = crcStr;
                final Bitmap tempBitmap = mBitmap;
                synchronized (asyncDraw)
                {
                    isDrawed = false;
                }
                insertImg();

                // imgPath不为空则表示图片来自媒体库或是拍照
                if (imgPath != null)
                {

                    drawCanvas();
                }
                new Thread()
                {
                    public void run()
                    {
                        try
                        {
                            File temp = new File(dataSource + "/photo");
                            if (!temp.exists())
                            {
                                temp.mkdirs();
                            }
                            FileOutputStream out = new FileOutputStream(new File(temp, Long.toHexString(tempCrc).toString().toUpperCase()));
                            tempBitmap.compress(CompressFormat.JPEG, 60, out);
                            out.close();
                        }
                        catch (IOException e)
                        {
                            e.printStackTrace();
                        }
                    };
                }.start();
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }

        public void insertImage(Intent mIntent, int requestCode)
        {
            Uri uri = mIntent.getData();
            try
            {
                selectImg = MediaStore.Images.Media.getBitmap(getContext()
                        .getContentResolver(), uri);
                Cursor c = getContext().getContentResolver().query(uri,
                        new String[]{MediaStore.Images.Media.DATA}, null, null,
                        null);
                String imgPath = null;
                if (c.moveToNext())
                {
                    imgPath = c.getString(0);
                }
                c.close();
                selectImg = matrix(selectImg);
                insertImage(selectImg, imgPath);
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
        }

        /**
         * 设置输出路径
         *
         * @param //path
         *            输出路径
         */
        // public void setOutPath(String path)
        // {
        // dataSource = path;
        // if (mRecorder != null)
        // {
        // mRecorder.setDataSource(path);
        // }
        // }

        private void getTrack()
        {
            if (mCurTrack == null)
            {
                switch (trackAction)
                {
                    case TrackBase.TRACK_ACTION_MOUSE:
                        TrackMouse mouse = new TrackMouse();
                        mouse.paint();
                        mCurTrack = mouse;
                        break;
                    case TrackBase.TRACK_ACTION_PHOTO:
                        mCurTrack = new TrackPhoto();
                        break;
                    case TrackBase.TRACK_ACTION_EASER:
                        TrackEaser easer = new TrackEaser();
                        easer.easer();
                        mCurTrack = easer;
                        mCurTrack.setColor(color);
                        mCurTrack.setWidth(TrackBase.EASER_WIDTH);
                        break;
                }
                if (mCurTrack != null)
                {
                    mCurTrack.setRecord();
                    if (TrackBase.TRACK_ACTION_EASER != trackAction)
                    {
                        mCurTrack.setColor(color);
                        // mCurTrack.setWidth(TrackBase
                        // .convertWidthIndexByIndex(widthIndex));
                        mCurTrack.setWidth(widthIndex);
                    }
                }
                mRecordTrack = mCurTrack;
            }
        }


        @Override
        public boolean onTouchEvent(MotionEvent event)
        {
            JournalActivity.isclear=-1;
            final int action = event.getActionMasked();
            final float x;
            final float y;
            switch (action)
            {
                case MotionEvent.ACTION_DOWN:

                    isDown = true;
                    getTrack();
                    x = event.getX();
                    y = event.getY();
                    if(mCurTrack!=null){
                        mCurTrack.touchDown(mCanvas, x, y);
                    }
                    break;
                // case MotionEvent.ACTION_POINTER_1_DOWN:
                // isDown = true;
                // isSingleTouch = false;
                // x = event.getX(1);
                // y = event.getY(1);
                // mCurTrack.touchUp(mCanvas);
                // mCurTrack.touchDown(mCanvas, x, y);
                // break;
                case MotionEvent.ACTION_MOVE:
                    JournalActivity.isWrite =true;
                    isWrite = true;
                    if (isSingleTouch)
                    {
                        x = event.getX();
                        y = event.getY();
                        if(mCurTrack!=null){
                            mCurTrack.move(x, y);
                        }
                    }
                    else
                    {
                        if (event.getPointerCount() == 1)
                        {
                            x = event.getX(1);
                            y = event.getY(1);
                            if(mCurTrack!=null){
                                mCurTrack.move(x, y);
                            }
                        }
                    }
                    drawCanvas();
                    break;
                // case MotionEvent.ACTION_POINTER_1_UP:
                // isSingleTouch = true;
                // isDown = false;
                // mCurTrack.touchUp(mCanvas);
                // x = event.getX();
                // y = event.getY();
                // mCurTrack.touchDown(mCanvas, x, y);
                // drawCanvas();
                // break;
                case MotionEvent.ACTION_CANCEL:
                case MotionEvent.ACTION_UP:

                    isDown = false;
                    mCurTrack.touchUp(mCanvas);
                    if (!isSingleTouch)
                    {
                        x = event.getX(1);
                        y = event.getY(1);
                        if(mCurTrack!=null){
                            mCurTrack.touchDown(mCanvas, x, y);
                        }
                    }
                    else
                    {
                        mCurTrack = null;
                    }
                    drawCanvas();
                    break;
            }
            return true;
        }

        /**
         * 设置当前动作
         *
         * @param action
         *            action<br />
         *            {@link TrackBase#TRACK_ACTION_CLS}<br />
         *            {@link TrackBase#TRACK_ACTION_MOUSE}<br />
         *            {@link TrackBase#TRACK_ACTION_PHOTO}
         */
        public void setTrackAction(int action)
        {
            trackAction = action;
            mCurTrack = null;
        }

        // /**
        // * 开始录屏
        // *
        // */
        // public void start()
        // {
        // isSaving = false;
        // mHeader = new TrackHeader();
        // mHeader.setBgColor(bgColor);
        // mHeader.setWidth(getMeasuredWidth());
        // mHeader.setHeight(getMeasuredWidth());
        // mHeader.setCreateTime(CWUtils.formatDate(System.currentTimeMillis()));
        // if (mRecorder == null)
        // {
        // initRecorder();
        // }
        // startTime = System.currentTimeMillis();
        // puaseTime = 0;
        // setOutPath(cacheFile.getAbsolutePath() + "/"
        // + CWUtils.md5(startTime + ""));
        // selectImg = mPallete.getScreen();
        // insertImage(selectImg, null);
        // mRecorder.start();
        // // CWLog.e("debug", "mRecorder1:" + mRecorder);
        // curRecordStatus = RECORD_STATUS_RECORDING;
        // }

        // /**
        // * 暂停后启动录屏
        // *
        // */
        // public void resume()
        // {
        // if (mRecorder != null)
        // {
        // // CWLog.e("debug", "mRecorder3:" + mRecorder);
        // mRecorder.resume();
        // puaseTime = System.currentTimeMillis() - puaseStartTime;
        // curRecordStatus = RECORD_STATUS_RECORDING;
        // selectImg = mPallete.getScreen();
        // insertImage(selectImg, null);
        // }
        // }

        // /**
        // * 暂停录屏
        // *
        // */
        // public void puase()
        // {
        // if (mRecorder != null)
        // {
        // // CWLog.e("debug", "mRecorder3:" + mRecorder);
        // mRecorder.puase();
        // puaseStartTime = System.currentTimeMillis();
        // curRecordStatus = RECORD_STATUS_PUASE;
        // }
        // }

        // /**
        // * 停止录屏
        // *
        // */
        // public void stop()
        // {
        // if (curRecordStatus != RECORD_STATUS_STOP
        // && curRecordStatus != RECORD_STATUS_NORMAL)
        // {
        // if (mRecorder == null)
        // {
        // throw new IllegalStateException("video record not init");
        // }
        // mRecorder.stop();
        // puaseTime = puaseStartTime == 0 ? 0 : System
        // .currentTimeMillis() - puaseStartTime;
        // curRecordStatus = RECORD_STATUS_STOP;
        // }
        // }

        // /**
        // * 恢复初始状态
        // *
        // */
        // public void reset()
        // {
        // curRecordStatus = RECORD_STATUS_NORMAL;
        // }

        /**
         * 清屏操作
         *
         */
        public void clsScreen()
        {
            final int w = getMeasuredWidth();
            final int h = getMeasuredHeight();
            if (w > 0 && h > 0)
            {
                bufferBitmap = null;
                mCanvas = null;
                initBufferBitmap(w, h);
                mRecordTrack = new TrackCls();
                trackAction = TrackBase.TRACK_ACTION_CLS;
                drawCanvas();
            }
        }

        @Override
        protected void onDraw(Canvas canvas)
        {
            canvas.drawBitmap(bufferBitmap, 0, 0, mPaint);
            if (mCurTrack != null && !(mCurTrack instanceof TrackEaser))
            {
                if (mCurTrack instanceof TrackPhoto)
                {
                    mCurTrack.draw(mCanvas);
                }
                else
                {
                    mCurTrack.draw(canvas);
                }
            }
            if (mCurTrack instanceof TrackEaser)
            {
                ((TrackEaser) mCurTrack).draw(mCanvas, canvas);
            }
            if (trackAction == TrackBase.TRACK_ACTION_PHOTO
                    || trackAction == TrackBase.TRACK_ACTION_CLS)
            {
                resetRecordStatus();
            }
            synchronized (asyncDraw)
            {
                isDrawed = true;
            }
        }

        private void drawCanvas()
        {
            // Canvas canvas = holder.lockCanvas();
            // if (canvas != null)
            // {
            // // mPaint.setDither(true);
            // // mPaint.setAntiAlias(true);
            // // mPaint.setFilterBitmap(true);
            // // canvas.setDrawFilter(new PaintFlagsDrawFilter(1,
            // // Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
            // canvas.drawBitmap(bufferBitmap, 0, 0, mPaint);
            // }
            // if (mCurTrack != null && !(mCurTrack instanceof TrackEaser))
            // {
            // mCurTrack.draw(mCanvas);
            // }
            // if (mCurTrack instanceof TrackEaser)
            // {
            // ((TrackEaser) mCurTrack).draw(mCanvas, canvas);
            // }
            // if (canvas != null)
            // {
            // holder.unlockCanvasAndPost(canvas);
            // }
            // Log.i("pallete", "mCurTrack:" + mCurTrack);
            invalidate();
        }
    }

    private void startAnim(int id, Animation anim)
    {
        View view = findViewById(id);
        startAnim(view, anim);
    }

    private void startAnim(View view, Animation anim)
    {
        view.clearAnimation();
        view.startAnimation(anim);
    }

}
